APM.util = {
	//时间解析器
	dateParser: {
		parse: function(value, culture, format, nullString, convertEmptyStringToNull) {
			var match;
			if (value instanceof Date) {
				return value;
			}
			if (!value || (value === "&nbsp;") || (value === nullString && convertEmptyStringToNull)) {
				return null;
			}
			match = /^\/Date\((\d+)\)\/$/.exec(value);
			if (match) {
				return new Date(parseInt(match[1], 10));
			}
			var date = Globalize.parseDate(value, format, culture.name);
			if (date == null || isNaN(date)) {
				date = Date.parse(value);
				date = isNaN(date) ? new Date(value) : new Date(date);
			}
			return date;
		},
		toStr: function(value, culture, format, nullString, convertEmptyStringToNull) {
			if (value === null && convertEmptyStringToNull) {
				return nullString;
			}
			return Globalize.format(value, format || "d", culture.name);
		}
	},
	/*
		快捷的将时间格式化输出
		date: 时间对象或满足条件的字符串
		format格式:
		d: "yyyy/M/d",
		D: "yyyy'年'M'月'd'日'",
		t: "H:mm",
		T: "H:mm:ss",
		f: "yyyy'年'M'月'd'日' H:mm",
		F: "yyyy'年'M'月'd'日' H:mm:ss",
		M: "M'月'd'日'",
		Y: "yyyy'年'M'月'"
	*/
	formatDate: function(date, format){
		var dateParser = APM.util.dateParser;
		var culture = Globalize.culture();
		return dateParser.toStr(dateParser.parse(date, culture, "yyyy'-'MM'-'dd'T'HH':'mm':'ssZ"), culture, format);
	},

	//解析url的查询参数
	getUrlParams: function(paramName) {
		var str = location.search.substr(1),
			arr = str == "" ? [] : str.split("&"),
			i,
			len = arr.length,
			itemArr,
			params = {};
		for (i = 0; i < len; i++) {
			itemArr = arr[i].split("=");
			params[itemArr[0]] = itemArr[1];
		}
		if (paramName) {
			if(params[paramName]){
				return decodeURIComponent(params[paramName]);
			}else{
				return undefined;
			}
		}
		return params;
	},

	escape: function (content) {
		return typeof content === 'string'
		? content.replace(/&(?![\w#]+;)|[<>"']/g, function (s) {
			return {
				"<": "&#60;",
				">": "&#62;",
				'"': "&#34;",
				"'": "&#39;",
				"&": "&#38;"
			}[s];
		})
		: content;
	},

	/**
		指标格式化
		@param {string} type 格式化类型
			transform_number_k	数字转换，使用k,m表示
			transform_number_thousand	数字转换，千分位表示法
			transform_time	转换时间，使用ms、s、m、h表示，输入单位是us
			transform_time_ms	转换时间，以毫秒表示，不带单位。输入单位是us
			transform_flow	转换流量，使用KB、MB、GB、TB表示，输入单位是byte
			transform_flow_mb	转换流量，总是以MB显示
			transform_flow_kb	转换流量，总是以KB显示
		@example APM.util.indicatorFormatter("transform_number_k")(32432);
	*/
	indicatorFormatter: function(type){
		var isNone = Ember.isNone;
		switch(type){
			case "transform_number_k":
				return function(val){
					if(isNone(val)){
						return "-";
					}
					val = parseInt(val, 10);
					if(val>999999){
						return (val/1000000).toFixed(0)+"m";
					}
					if(val>9999){
						return (val/1000).toFixed(0)+"k";
					}
					return val;
				}
			case "transform_number_thousand":
				return function(val){
					var reg=/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g;
					return isNone(val)?"-":String(val).replace(reg, '$&,');
				}
			case "transform_time":
				return function(val){
					if(isNone(val)){
						return "-";
					}
					val = parseInt(val, 10);
					if (val < 2000) {
						return (val/1000).toFixed(3) + "ms";
					} else if (val < 1000000) {
						return (val/1000).toFixed(0) + "ms";
					} else if (val < 60000000){
						return (val/1000000).toFixed(0) + "s";
					} else if (val < 3600000000){
						return  (val/60000000).toFixed(0) + "m";
					} else {
						return  (val/3600000000).toFixed(0) + "h";
					}
				}
			case "transform_num":
				return function(val){
					if(isNone(val)){
						return "-";
					}
					val = parseInt(val, 10);
					if (val < 2000) {
						return (val/1000).toFixed(3);
					} else if (val < 1000000) {
						return (val/1000).toFixed(0);
					} else if (val < 60000000){
						return (val/1000000).toFixed(0);
					} else if (val < 3600000000){
						return  (val/60000000).toFixed(0);
					} else {
						return  (val/3600000000).toFixed(0); 
					}
				}
			case "transform_time_ms":
				return function(val){
					if(isNone(val)){
						return "-";
					}
					val = parseInt(val, 10);
					if (val < 2000) {
						return (val/1000).toFixed(3) + "ms";
					} else if (val < 1000000) {
						return (val/1000).toFixed(0) + "ms";
					}
				}
			case "transform_time_ms_f":
				return function(val){
					if(isNone(val)){
						return "-";
					}
					val = parseFloat(val, 10);
					if (val < 2000) {
						return (val/1000).toFixed(3) + "ms";
					} else if (val < 1000000) {
						return (val/1000).toFixed(0) + "ms";
					}
				}
			case "transform_flow":
				return APM.util.flowFormatter;
			case "transform_flow_mb":
				return function(val){
					return  isNone(val)?"-":(val/1024/1024).toFixed(2) + "MB";
				}
			case "transform_flow_kb":
				return function(val){
					return  isNone(val)?"-":(val/1024).toFixed(2) + "KB";
				}
			default:
				return function(val){
					return isNone(val)?"-":val;
				}
		}
	},

	/**
		用于grid的指标格式化函数
	*/
	indicatorCellFormatter: function(args, colume){
		if (args.row.type & $.wijmo.wijgrid.rowType.data) {
			var $container = args.$container,
				val = Ember.get(args.row.data, colume.dataKey);
			$container.html( APM.util.indicatorFormatter(colume._fmtType)(val) );
			return true;
		}
	},

	flowFormatter: function(val){
		if(Ember.isNone(val)){
			return "-";
		}
		if (val < 1024) {
			return val;
		} else if (val < 1024*1024){
			return (val/1024).toFixed(2) + "KB";
		} else if (val < 1024*1024*1024){
			return  (val/1024/1024).toFixed(2) + "M";
		} else if (val < 1024*1024*1024*1024){
			return  (val/1024/1024/1024).toFixed(2) + "G";
		} else if (val < 1024*1024*1024*1024*1024){
			return (val/1024/1024/1024/1024).toFixed(2) + "T";
		} else{
			return (val/1024/1024/1024/1024/1024).toFixed(2) + "P";
		}
	}
};

/*----------应用系统公用的函数集合----------*/
function alertDialog(htmlstr, config) {
	return new Ember.RSVP.Promise(function(resolve, reject){
		require(
			[
				"broada/ui/dialog"
			],
			function(){
				config = config || {};
				var $dialog = $('<div></div>')
				.html(htmlstr)
				.appendTo("body")
				.wijdialog({
					title: config.title || "提醒",
					width: config.width || 300,
					height: config.height || "auto",
					modal: true,
					minHeight: 100,
					maxHeight: 500,
					captionButtons: {
						pin: { visible: false },
						refresh: { visible: false },
						toggle: { visible: false },
						minimize: { visible: false },
						maximize: { visible: false }
					},
					buttons: {
						ok: {
							text: "确定",
							"class": "btn btn-primary",
							click: function(){
								$dialog.wijdialog("close");
								resolve();
							}
						}
					},
					create: function(){
						$(this).parent().addClass("apm-dialog-alert");
					},
					close: function(){
						$(this).wijdialog("destroy").remove();
						resolve();
					}
				});
			}
		);
	});
}

function confirmDialog(htmlstr, config) {
	return new Ember.RSVP.Promise(function(resolve, reject){
		require(
			[
				"broada/ui/dialog"
			],
			function(){
				config = config || {};
				var $dialog = $('<div></div>')
				.html(htmlstr)
				.appendTo("body")
				.wijdialog({
					title: config.title || "确认",
					width: config.width || 400,
					height: config.height || "auto",
					modal: true,
					minHeight: 100,
					maxHeight: 500,
					captionButtons: {
						pin: { visible: false },
						refresh: { visible: false },
						toggle: { visible: false },
						minimize: { visible: false },
						maximize: { visible: false }
					},
					buttons: {
						ok: {
							text: "确定",
							"class": "u-btn-blue",
							click: function(){
								$dialog.wijdialog("close");
								resolve();
							}
						},
						cancel: {
							text: "取消",
							"class": "u-btn-blue",
							click: function(){
								$dialog.wijdialog("close");
								reject();
							}
						}
					},
					create: function(){
						$(this).parent().addClass("apm-dialog-confirm");
					},
					close: function(e){
						$(this).wijdialog("destroy").remove();
						if(e.which){
							reject();
						}
					}
				});
			}
		);
	});
}

function alertTip(htmlStr, type){
	require(
		[
			"broada/ui/message"
		],
		function(Message){
			var typeMap = {
				"info": true,
				"error": true,
				"warn": true,
				"success": true
			};
			if(!typeMap[type]){
				type = "info";
			}
			Message[type]&&Message[type](htmlStr);
		}
	);
}

function createApp(name){
	var appDir = "./apps/" + name + "/";
	var App = Ember.Namespace.create({
		name: name,
		sysDir: ".",
		appDir: appDir,
		tplDir: appDir + "tpls/"
	});
	App.Route = Ember.Route.extend({
		templateLoader: "broada/base/text",

		templateDir: ".",

		setup: function(){
			this._prepareTemplates();
			this._prepareDeps();
			this._super.apply(this, arguments);
		},

		_prepareTemplates: function(){
			if(this.__prepareTemplates){
				return;
			}
			this.__prepareTemplates = true;
			var templateName = this.routeName.replace(/\./g, '/');
			var defaultTpl = {
				name: templateName,
				url: App.tplDir + this.routeName.replace(/\./g, '_') + ".hbs"
			};
			var templates = this.templates || [];
			var forEach = Ember.EnumerableUtils.forEach;
			var hasDefautl = false;

			forEach(templates, function(tpl, i, arr){
				if(Ember.typeOf(tpl) == "string"){
					tpl = {
						name: tpl,
						url: App.tplDir + tpl.replace(/\//g, '_') + ".hbs"
					};
					arr[i] = tpl;
				}else{
					if(tpl.url.indexOf("/") == 0){
						tpl.url = App.sysDir + tpl.url;
					}else if(tpl.url.indexOf("./") == 0){
						tpl.url = App.tplDir + tpl.url.substring(2);
					}
				}

				if(tpl.name == templateName){
					hasDefautl = true;
				}
			});
			if(!this.templates && !hasDefautl){
				this.templates = [defaultTpl].concat(templates);
			}
		},

		_prepareDeps: function(){
			if(this.__prepareDeps){
				return;
			}
			this.__prepareDeps = true;
			var deps = this.dependences||[];
			var forEach = Ember.EnumerableUtils.forEach;

			forEach(deps, function(depItem, i, arr){
				if(depItem.indexOf("/") == 0){
					arr[i] = App.sysDir + depItem;
				}else if(depItem.indexOf("./") == 0){
					arr[i] = App.appDir + depItem.substring(2);
				}
			});
		}
	});

	App.routerMap = function(fn){
		APM.Router.map(function() {
			this.route(name, fn);
		});
	};

	return App;
}